package com.sdkx.wear_os.base

import android.annotation.SuppressLint
import android.app.Activity
import android.app.Application
import android.app.Dialog
import android.content.Context
import android.graphics.Typeface
import android.view.LayoutInflater
import android.view.View.GONE
import android.widget.TextView
import androidx.lifecycle.AndroidViewModel
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.lihang.ShadowLayout
import com.sdkx.wear_os.bean.DialogBean
import com.sdkx.wear_os.customview.customizeDialogBottom
import com.sdkx.wear_os.customview.customizeDialogCenter
import com.sdkx.wear_os.utils.ToastLogUtils
import com.sdkx.wear_os.utils.isApkInDebug
import com.sdkx.wear_os.R
import com.sdkx.wear_os.adapter.DialogAdapter
import com.sdkx.wear_os.app.MyApplication
import com.sdkx.wear_os.pickerview.builder.TimePickerBuilder
import com.sdkx.wear_os.pickerview.listener.OnTimeSelectListener
import com.sdkx.wear_os.pickerview.view.TimePickerView
import com.sdkx.wear_os.pickerview.view.WheelView
import com.sdkx.wear_os.retrofit.Bean
import com.sdkx.wear_os.retrofit.Parameter
import com.sdkx.wear_os.retrofit.launch
import com.sdkx.wear_os.retrofit.response.RetrofitManager
import com.sdkx.wear_os.utils.stringToDate
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.launch
import java.io.File
import java.util.*

/**
 * viewModel基类
 */
open class BaseViewModel constructor(
    application: Application
) : AndroidViewModel(application) {

    //列表页数
    var page = 1

    //网络请求参数
    val parameter = Parameter()

    //请求类
    val retrofitManager = RetrofitManager()

    //多文件上传观察者
    var fileListFlow: MutableSharedFlow<List<Bean>>? = null

    //文件上传观察者
    var fileFlow: MutableSharedFlow<Bean>? = null

    //日期观察者
    var dateFlow: MutableSharedFlow<Date?>? = null

    //弹窗选项观察者
    var dialogFlow: MutableSharedFlow<MutableList<DialogBean>>? = null

    //中间弹窗
    var centerDialogFlow: MutableSharedFlow<Boolean>? = null

    //加载框
    val loadingChange: UiLoadingChange by lazy { UiLoadingChange() }

    //软键盘监听
    var isShowKey = MutableSharedFlow<Int>()

    //刷新
    @SuppressLint("StaticFieldLeak")
    var swipe: SwipeRefreshLayout? = null
        set(swipe) {
            swipe?.setColorSchemeResources(R.color.purple_3F7FFB)
            field = swipe
        }

    /**
     * 内置封装好的可通知Activity/fragment 显示隐藏加载框 因为需要跟网络请求显示隐藏loading
     */
    inner class UiLoadingChange {
        //显示加载框
        val showDialog = MutableSharedFlow<Boolean>()
    }

    /**
     * 上传多文件
     */
    fun upLoadsFile(file: MutableList<File>) {
        launch({ RetrofitManager().upLoadsFile(file) }, {
            MainScope().launch {
                fileListFlow?.emit(it)
            }
        }, {
            ToastLogUtils.toastUtil(it)
        }, {
        }, true, "uploads")
    }

    /**
     * 上传文件
     */
    fun uploadFile(file: File) {
        launch({ RetrofitManager().uploadFile(file) }, {
            MainScope().launch {
                fileFlow?.emit(it)
            }
        }, {
            ToastLogUtils.toastUtil(it)
        }, {
        }, true, "upload")
    }

    /**
     * 上传错误日志
     */

    fun uploadError(parameter: Parameter) {
        if (isApkInDebug(MyApplication.application)) {
            return
        }
//        parameter.appVersion = getVersionName(getApplication())
//        parameter.phoneBrand = getSystemBrand()
//        parameter.phoneModel = getSystemModel()
//        parameter.phoneVersion = getSystemRelease()
//        launch({ RetrofitManager().uploadError(parameter) }, {
//        }, {
//        }, {
//        }, false, "uploadError")
    }

    /**
     * 时间选择器 ，自定义布局
     * @param selectedDateStr 当前选中日期 yyyy-MM-dd
     * @param type 类型 0 区域时间 1之前时间 2之后时间
     * @param showType 年月日时分秒
     */
    fun selectTime(
        context: Activity,
        selectedDateStr: String = "",
        type: Int = 0,
        showType: BooleanArray = booleanArrayOf(true, true, true, false, false, false)
    ): TimePickerView {
        var pvTime: TimePickerView? = null
        //选中日期
        val selectedDate: Calendar = Calendar.getInstance()
        selectedDate.time = stringToDate(selectedDateStr)
        //开始日期
        val startDate = Calendar.getInstance()
        //结束日期
        val endDate = Calendar.getInstance()
        when (type) {
            0 -> {
                startDate.time = stringToDate("2021-01-01")
                endDate.time = stringToDate("2030-12-31")
            }
            1 -> {
                startDate.time = stringToDate("2021-01-01")
            }
            else -> {
                endDate.time = stringToDate("2030-12-31")
            }
        }
        pvTime = TimePickerBuilder(context,
            OnTimeSelectListener { date, v ->
                MainScope().launch {
                    dateFlow?.emit(date)
                }
            })
            .setDate(selectedDate)
            .setRangDate(startDate, endDate)
            .setItemVisibleCount(3)
            .setLineSpacingMultiplier(3f)
            .setType(showType)
            .setLayoutRes(
                R.layout.dialog_date_select
            ) {
                val year = it.findViewById<WheelView>(R.id.year)
                val month = it.findViewById<WheelView>(R.id.month)
                val day = it.findViewById<WheelView>(R.id.day)
                val hour = it.findViewById<WheelView>(R.id.hour)
                val min = it.findViewById<WheelView>(R.id.min)
                val cancel = it.findViewById<TextView>(R.id.cancel)
                val sure = it.findViewById<TextView>(R.id.sure)
                year.setTypeface(Typeface.DEFAULT)
                month.setTypeface(Typeface.DEFAULT)
                day.setTypeface(Typeface.DEFAULT)
                hour.setTypeface(Typeface.DEFAULT)
                min.setTypeface(Typeface.DEFAULT)
                cancel.setOnClickListener {
                    MainScope().launch {
                        dateFlow?.emit(null)
                    }
                    pvTime?.dismiss()
                }
                sure.setOnClickListener {
                    pvTime?.returnData()
                    pvTime?.dismiss()
                }
            }
            .setDecorView(context.window.decorView.findViewById(android.R.id.content))
            .build()
        return pvTime
    }

    /**
     * 列表选择器 不分页 下方弹出
     * @param isSingle 是否单选
     * @param data 数据
     * @param title 标题
     * @param height 高度
     * @param isChangeColor 是否改变颜色
     */
    @SuppressLint("NotifyDataSetChanged")
    fun selectDialog(
        context: Context,
        isSingle: Boolean,
        data: MutableList<DialogBean>,
        title: String = "请选择",
        height: Int = MyApplication.getHeight() / 2,
        isChangeColor: Boolean = true
    ): Dialog {
        val dialogView =
            LayoutInflater.from(context).inflate(R.layout.dialog_recyclerview, null)
        val dialog = customizeDialogBottom(context, dialogView, true, height)
        dialogView.findViewById<TextView>(R.id.recyclerview_dialog_title).text = title
        val dialogAdapter = DialogAdapter(isSingle, isChangeColor)
        dialogAdapter.submitList(data)
        //如果单选 隐藏下发的确定按钮
        if (isSingle) {
            dialogView.findViewById<TextView>(R.id.dialog_sure).visibility = GONE
        }
        //取消
        dialogView.findViewById<TextView>(R.id.dialog_cancel).setOnClickListener {
            dialog.dismiss()
        }
        //确定
        dialogView.findViewById<TextView>(R.id.dialog_sure).setOnClickListener {
            dialog.dismiss()
            val dialogData = mutableListOf<DialogBean>()
            dialogAdapter.items.forEach {
                if (it.isSelect) {
                    dialogData.add(it)
                }
            }
            if (dialogData.isEmpty()) {
                ToastLogUtils.toastUtil("请至少选择一项")
                return@setOnClickListener
            }
            MainScope().launch {
                dialogFlow?.emit(dialogData)
            }
        }
        dialogView.findViewById<RecyclerView>(R.id.dialog_recyclerview).apply {
            layoutManager = LinearLayoutManager(context)
            adapter = dialogAdapter
        }
        dialogAdapter.setOnItemClickListener { adapter, view, position ->
            if (dialogAdapter.items[position].isGray) {
                return@setOnItemClickListener
            }
            if (isSingle) {
                dialog.dismiss()
                val dialogData = mutableListOf<DialogBean>()
                dialogData.add(dialogAdapter.items[position])
                MainScope().launch {
                    dialogFlow?.emit(dialogData)
                }
                dialogAdapter.items.indices.forEach {
                    dialogAdapter.items[it].isSelect = it == position
                }
                dialogAdapter.notifyDataSetChanged()
            } else {
                dialogAdapter.items[position].isSelect = !dialogAdapter.items[position].isSelect
                dialogAdapter.notifyItemChanged(position)
            }
        }
        return dialog
    }

    /**
     * 中间弹窗
     * @param title 标题
     * @param content 内容
     */
    fun centerDialog(
        context: Context,
        title: String,
        content: String,
    ): Dialog {
        val dialogView =
            LayoutInflater.from(context).inflate(R.layout.dialog_center, null)
        val dialog = customizeDialogCenter(context, dialogView, true)
        dialogView.findViewById<TextView>(R.id.dialog_title).text = title
        dialogView.findViewById<TextView>(R.id.dialog_content).text = content
        //取消
        dialogView.findViewById<ShadowLayout>(R.id.cancel_button).setOnClickListener {
            MainScope().launch {
                centerDialogFlow?.emit(false)
            }
            dialog.dismiss()
        }
        //确定
        dialogView.findViewById<ShadowLayout>(R.id.sure_button).setOnClickListener {
            MainScope().launch {
                centerDialogFlow?.emit(true)
            }
            dialog.dismiss()
        }
        return dialog
    }
}